<script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from 'vue'
import { useUserStore } from '@/stores'
import { getLogAPI, updatePasswordAPI, updatePhoneAPI } from '@/api/user'
import type { LogDataType } from '@/interface'
import { formatDate, formatGender } from '@/utils/format'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { updateMineInfoAPI } from '@/api/user'
import UploadAvatar from './components/UploadAvatar.vue'
import { Plus } from '@element-plus/icons-vue'
import { debounce } from 'lodash'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { checkQRCodeAPI, getCodeAPI, getQRCodeAPI } from '@/api/login'
import { checkPhone } from '@/utils/utils'
import { socket } from '@/utils/socket'

const router = useRouter()
const { t } = useI18n()

const userStore = useUserStore()

const activeName = ref('first')

// 用户动态
const stuLogListParams = ref({
  pageIndex: 1,
  pageSize: 10,
  id: userStore.userData?.id
})
const stuLogList = ref<LogDataType[]>([])
const isOver = ref(false)
const getStuLogList = async () => {
  if (isOver.value) {
    return
  }
  const { data: res } = await getLogAPI(stuLogListParams.value)
  if (res.status === 200) {
    if (res.data.length < stuLogListParams.value.pageSize) {
      isOver.value = true
    }
    stuLogList.value = [...stuLogList.value, ...res.data]
  }
}
getStuLogList()

const scrollRef = ref()
const scrollTop = ref(0) // 记录数据加载前滚动条的位置，用来手动定位scrollbar
const handleScroll = debounce((e) => {
  const wrapRef = scrollRef.value.wrapRef
  scrollRef.value.moveY = (wrapRef.scrollTop * 100) / wrapRef.clientHeight
  const poor = wrapRef.scrollHeight - wrapRef.clientHeight
  if (e.scrollTop + 2 > poor) {
    scrollTop.value = e.scrollTop
    stuLogListParams.value.pageIndex += 1
  }
}, 100)

watch(
  () => stuLogListParams.value.pageIndex,
  () => {
    if (stuLogListParams.value.pageIndex > 1 && !isOver.value) {
      getStuLogList()
    }
  }
)

// 用户资料
const editFormData = ref({
  id: userStore.userData.id,
  real_name: userStore.userData.real_name,
  age: userStore.userData.age,
  gender: userStore.userData.gender,
  birth_day: userStore.userData.birth_day
})

const editFormRef = ref<FormInstance>()
const editFormRules: FormRules = {
  real_name: [
    {
      required: true,
      message: t('CENTER.REAL_NAME_PLACEHOLDER'),
      trigger: ['change', 'blur']
    }
  ],
  gender: [
    {
      required: true,
      message: t('CENTER.GENDER_PLACEHOLDER'),
      trigger: ['change', 'blur']
    }
  ]
}

const submit = () => {
  editFormRef.value?.validate(async (r) => {
    if (r) {
      const { data: res } = await updateMineInfoAPI(editFormData.value)
      if (res.status === 200) {
        ElMessage.success(res.message)
        userStore.getUserData(editFormData.value.id as number)
      } else {
        ElMessage.error(res.message)
      }
    } else {
      return false
    }
  })
}

// 修改密码
const passwordRef = ref<FormInstance>()
const passwordData = ref({
  newPassword: '',
  confirmPassword: ''
})
const checkPassword = (rule: any, value: any, callback: Function) => {
  const regex = /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{6,}$/
  if (value === '') {
    callback(new Error(t('CENTER.NEW_PASSWORD_PLACEHOLDER')))
  }
  if (!regex.test(value)) {
    callback(new Error(t('CENTER.NEW_PASSWORD_RULES')))
  }
  if (passwordData.value.confirmPassword !== '') {
    if (passwordData.value.confirmPassword === value) {
      callback()
    }
    passwordRef.value?.validateField('confirmPassword')
  }
  callback()
}
const checkConfirmPassword = (rule: any, value: any, callback: Function) => {
  if (value === '') {
    callback(new Error(t('CENTER.CONFIRM_PASSWORD_PLACEHOLDER')))
  }
  if (value === passwordData.value.newPassword) {
    callback()
  } else {
    callback(new Error(t('CENTER.NEW_AND_OLD_PASSWORD')))
  }
}
const passwordRules: FormRules = {
  newPassword: [
    {
      required: true,
      validator: checkPassword,
      trigger: 'change'
    }
  ],
  confirmPassword: [
    {
      required: true,
      validator: checkConfirmPassword,
      trigger: 'change'
    }
  ]
}

const changePassword = async () => {
  await passwordRef.value?.validate()
  const { data: res } = await updatePasswordAPI({
    newPassword: passwordData.value.confirmPassword
  })
  if (res.status === 200) {
    return ElMessage({
      type: 'success',
      message: res.message,
      onClose: () => {
        localStorage.removeItem('option')
        localStorage.removeItem('uid')
        localStorage.removeItem('t')
        localStorage.removeItem('user')
        router.push('/login')
      }
    })
  }
  ElMessage.error(res.message)
}
const resetPasswordValidate = () => {
  passwordRef.value?.resetFields()
}

// 修改手机
const phoneData = ref({
  id: userStore.userData.id as number,
  phone: userStore.userData.phone as string,
  code: ''
})
const phoneRef = ref<FormInstance>()
const phoneRules: FormRules = {
  phone: [{ required: true, validator: checkPhone, trigger: 'change' }],
  code: [
    {
      required: true,
      message: t('CENTER.CODE_PLACEHOLDER'),
      trigger: ['blur', 'change'],
      min: 4,
      max: 4
    }
  ]
}

// 获取验证码
let n: any = null
const time = ref(60)
const isDisabled = ref(false)
const getCode = async () => {
  await phoneRef.value?.validateField(['phone'])
  const { data: res } = await getCodeAPI(phoneData.value.phone)
  if (res.status === 200) {
    ElMessage.success(res.message)
    isDisabled.value = true
    n = setInterval(() => {
      time.value--
      if (time.value === 0) {
        isDisabled.value = false
        time.value = 60
        clearInterval(n)
      }
    }, 1000)
  } else {
    ElMessage.error(res.message)
  }
}
onUnmounted(() => {
  clearInterval(n)
})

const changePhone = async () => {
  await phoneRef.value?.validate()
  const { data: res } = await updatePhoneAPI(phoneData.value)
  if (res.status === 200) {
    return ElMessage.success(res.message)
  }
  ElMessage.error(res.message)
}

const resetPhoneValidate = () => {
  phoneRef.value?.resetFields(['phone', 'code'])
}

// 绑定微信

// 绑定微信
const bindWxDialog = ref(false)
const wxQRCode = ref('')
const timeout = ref<any>(null)
const scene = ref('')
const wxQRCodeStatus = ref(false)
const getQRCode = async () => {
  clearInterval(timeout.value)
  const { data: res } = await getQRCodeAPI({
    status: true,
    userId: `${userStore.userData.id}`,
    use: 1
  })
  if (res.status === 200) {
    wxQRCode.value = res.data
    scene.value = res.scene
    socket.emit('loginQRCodeStatus', scene.value)

    timeout.value = setInterval(async () => {
      const { data: checkRes } = await checkQRCodeAPI(res.scene)
      if (checkRes.status === 200) {
        wxQRCodeStatus.value = true
        clearInterval(timeout.value)
      }
      if (checkRes.status === 400) {
        wxQRCode.value = ''
        clearInterval(timeout.value)
      }
    }, 3000)
  }
}
const openBindWxDialog = () => {
  bindWxDialog.value = true
  getQRCode()
}
const closeBindWxDialog = () => {
  clearInterval(timeout.value)
  timeout.value = null
  wxQRCode.value = ''
  scene.value = ''
  wxQRCodeStatus.value = false
  bindWxDialog.value = false
}

onMounted(() => {
  socket.off('resendLoginStatus')
  socket.on('resendLoginStatus', (data) => {
    if (data.status === 200) {
      ElMessage.success(data.message)
      closeBindWxDialog()
      userStore.getUserData()
    }
  })
})
</script>

<template>
  <div class="center-container">
    <div class="center-about">
      <el-card shadow="never" style="margin-bottom: 1.25rem">
        <template #header>
          <h3>{{ $t('CENTER.ABOUT_ME') }}</h3>
        </template>
        <div class="center-about-avatar">
          <UploadAvatar>
            <el-avatar
              class="user-card-avatar"
              :size="100"
              :src="userStore.userData?.image_path"
              v-if="userStore.userData?.image_path"
            />
            <el-icon v-else class="user-card-avatar-icon">
              <Plus />
            </el-icon>
          </UploadAvatar>
          <h3 style="margin-top: 20px">
            {{ userStore.userData.user_name }}
          </h3>
        </div>
        <div class="center-about-info">
          <ul>
            <li>
              <span>{{ $t('CENTER.REAL_NAME') }} : </span>
              {{ userStore.userData.real_name }}
            </li>
            <li>
              <span>{{ $t('CENTER.AGE') }} : </span>
              {{ userStore.userData.age }}
            </li>
            <li>
              <span>{{ $t('CENTER.GENDER') }} : </span>
              {{
                userStore.userData.gender &&
                formatGender(userStore.userData.gender)
              }}
            </li>
            <li>
              <span>{{ $t('CENTER.PHONE') }} : </span>
              {{ userStore.userData.phone }}
            </li>
            <li>
              <span>{{ $t('CENTER.BIRTHDAY') }} : </span>
              {{
                userStore.userData.birth_day &&
                formatDate(userStore.userData.birth_day, 'YYYY-MM-DD')
              }}
            </li>
          </ul>
          <el-button
            style="margin-top: 0.1rem"
            v-if="!userStore.userData.bindWxStatus"
            @click="openBindWxDialog"
          >
            绑定微信
          </el-button>
        </div>
      </el-card>
    </div>
    <div class="center-data">
      <el-card style="height: 100%" shadow="never">
        <el-tabs v-model="activeName" style="height: 100%">
          <el-tab-pane
            :label="$t('CENTER.UPDATE')"
            name="first"
            style="height: 100%"
          >
            <el-scrollbar height="100%" @scroll="handleScroll" ref="scrollRef">
              <el-timeline style="max-width: 600px">
                <el-timeline-item
                  size="large"
                  :timestamp="formatDate(item.create_time, 'YYYY-MM-DD')"
                  placement="top"
                  v-for="item in stuLogList"
                  :key="item.id"
                >
                  <el-card>
                    <h3 style="margin-bottom: 1.25rem">
                      {{ item.real_name }} {{ item.content }}
                    </h3>
                    <p>
                      {{ formatDate(item.create_time, 'YYYY-MM-DD HH:mm:ss') }}
                    </p>
                  </el-card>
                </el-timeline-item>
              </el-timeline>
            </el-scrollbar>
          </el-tab-pane>
          <el-tab-pane :label="$t('CENTER.ACCOUNT_INFO')" name="second">
            <el-form
              :model="editFormData"
              ref="editFormRef"
              :rules="editFormRules"
              label-width="6.25rem"
            >
              <el-form-item prop="real_name">
                <template #label>
                  <div class="edit-form-item-label">
                    {{ $t('CENTER.REAL_NAME') }} :
                  </div>
                </template>
                <el-input
                  v-model="editFormData.real_name"
                  style="width: 15rem"
                  :placeholder="$t('CENTER.REAL_NAME_PLACEHOLDER')"
                  clearable
                />
              </el-form-item>
              <el-form-item prop="age">
                <template #label>
                  <div class="edit-form-item-label">
                    {{ $t('CENTER.AGE') }} :
                  </div>
                </template>
                <el-input-number
                  v-model="editFormData.age"
                  style="width: 15rem"
                  :min="22"
                  :max="70"
                />
              </el-form-item>
              <el-form-item prop="gender">
                <template #label>
                  <div class="edit-form-item-label">
                    {{ $t('CENTER.GENDER') }} :
                  </div>
                </template>
                <el-select
                  v-model="editFormData.gender"
                  style="width: 15rem"
                  :placeholder="$t('CENTER.GENDER_PLACEHOLDER')"
                  clearable
                >
                  <el-option :label="$t('USER_MANAGE.MAN')" :value="1" />
                  <el-option :label="$t('USER_MANAGE.WOMAN')" :value="0" />
                </el-select>
              </el-form-item>
              <el-form-item prop="birth_day">
                <template #label>
                  <div class="edit-form-item-label">
                    {{ $t('CENTER.BIRTHDAY') }} :
                  </div>
                </template>
                <el-date-picker
                  v-model="editFormData.birth_day"
                  type="date"
                  :placeholder="$t('CENTER.BIRTHDAY_PLACEHOLDER')"
                  style="width: 15rem"
                />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="submit">{{
                  $t('CENTER.SUBMIT')
                }}</el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>
          <el-tab-pane :label="$t('CENTER.UPDATE_PASSWORD')">
            <el-form
              ref="passwordRef"
              :model="passwordData"
              :rules="passwordRules"
              label-width="200px"
            >
              <el-form-item
                :label="$t('CENTER.NEW_PASSWORD')"
                prop="newPassword"
              >
                <el-input
                  style="width: 300px"
                  v-model="passwordData.newPassword"
                  :placeholder="$t('CENTER.NEW_PASSWORD_PLACEHOLDER')"
                ></el-input>
              </el-form-item>
              <el-form-item
                :label="$t('CENTER.CONFIRM_PASSWORD')"
                prop="confirmPassword"
              >
                <el-input
                  style="width: 300px"
                  v-model="passwordData.confirmPassword"
                  :placeholder="$t('CENTER.CONFIRM_PASSWORD_PLACEHOLDER')"
                ></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="changePassword">
                  提交
                </el-button>
                <el-button @click="resetPasswordValidate"> 重置 </el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>
          <el-tab-pane :label="$t('CENTER.UPDATE_PHONE')">
            <el-form
              ref="phoneRef"
              :model="phoneData"
              :rules="phoneRules"
              label-width="200px"
            >
              <el-form-item :label="$t('CENTER.PHONE')" prop="phone">
                <el-input
                  style="width: 30%; margin-right: 0.1rem"
                  :placeholder="$t('CENTER.PHONE_PLACEHOLDER')"
                  v-model="phoneData.phone"
                  :disabled="isDisabled"
                ></el-input>
                <el-button :disabled="isDisabled" @click="getCode">
                  {{ time < 60 ? time : $t('CENTER.GET_CODE') }}
                </el-button>
              </el-form-item>
              <el-form-item :label="$t('CENTER.CODE')" prop="code">
                <el-input
                  style="width: 30%"
                  :placeholder="$t('CENTER.CODE_PLACEHOLDER')"
                  v-model="phoneData.code"
                  maxlength="4"
                ></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="changePhone">
                  {{ $t('PAPER.SUBMIT') }}
                </el-button>
                <el-button @click="resetPhoneValidate">
                  {{ $t('PAPER.RESET') }}
                </el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>
        </el-tabs>
      </el-card>
    </div>
  </div>
  <el-dialog
    v-model="bindWxDialog"
    title="绑定微信"
    width="20%"
    @close="closeBindWxDialog"
  >
    <div class="user-bind-wx">
      <el-image style="width: 100%; height: 100%" :src="wxQRCode" fit="fit">
        <template #error>
          <div class="image-slot" @click="getQRCode">
            <el-icon><i-ep-picture /></el-icon>
            <span>点击重新获取二维码</span>
          </div>
        </template>
      </el-image>
      <span class="user-wx-qrcode-scan" v-if="wxQRCodeStatus"> 已扫码 </span>
    </div>
  </el-dialog>
</template>

<style lang="scss" scoped>
.center-container {
  height: 100%;
  display: flex;
  overflow: auto;

  .center-about {
    flex: 1;
    margin-right: 1.25rem;
    .center-about-avatar {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      margin-bottom: 1.25rem;
    }

    .center-about-info {
      span {
        display: inline-block;
        width: 5rem;
        text-align: right;
        color: #838383;
        margin-right: 0.375rem;
      }
    }
    .center-about-wx {
      :deep(.el-card__body) {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  }
  .center-data {
    flex: 3;
    &:deep(.el-card__body) {
      height: 100%;
    }

    &:deep(.el-tabs__content) {
      height: calc(100% - 40px);
    }
    &:deep(.el-scrollbar__wrap) {
      padding-left: 0.625rem;
    }
  }
}
.user-bind-wx {
  position: relative;
  .image-slot {
    cursor: pointer;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 350px;
    height: 350px;
    background: var(--el-fill-color-light);
    color: var(--el-text-color-secondary);
    font-size: 30px;
    .el-icon {
      width: 30px;
      height: 30px;
    }
    span {
      font-size: 14px;
      margin-top: 40px;
    }
  }
  .user-wx-qrcode-scan {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    padding: 20px;
    backdrop-filter: blur(3px);
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: 600;
    font-size: 24px;
    letter-spacing: 4px;
  }
}
</style>
